package com.hcloud.libupload.http

import com.hcloud.libupload.request.UploadRequest
import okhttp3.MediaType
import okhttp3.RequestBody
import okio.BufferedSink
import okio.Source
import okio.source
import java.io.ByteArrayInputStream

class ProgressBody(
    private val uploadRequest: UploadRequest,
    private val requestBody: RequestBody,
    private val progress: Progress,
    private val partInputStream: ByteArrayInputStream
) : RequestBody() {

    private val SEGMENT_SIZE = 2048

    override fun contentType(): MediaType? {
        return requestBody.contentType()
    }

    override fun contentLength(): Long {
        return requestBody.contentLength()
    }

    override fun isOneShot(): Boolean {
        return true
    }


    override fun writeTo(sink: BufferedSink) {
        val source: Source = partInputStream.source()
        var read: Long = 0
        var toRead: Long
        var remain: Long

        while (read < requestBody.contentLength()) {

            remain = requestBody.contentLength() - read
            toRead = remain.coerceAtMost(SEGMENT_SIZE.toLong())
            read = source.read(sink.buffer, toRead)

            if (read == -1L) {
                break
            }

            sink.flush()

            if (read != 0L) {
                progress.progressChange(uploadRequest, read)
            }
        }

        source.close()
    }

}